home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cocktail / puma.lha / puma / src / c.puma < prev    next >
Text File  |  1992-09-25  |  29KB  |  1,143 lines

  1. /* Ich, Doktor Josef Grosch, Informatiker, 21.6.1991 */
  2.  
  3. TRAFO C
  4. TREE Tree
  5. PUBLIC DefC ImplC MacroC
  6.  
  7. GLOBAL {
  8.  
  9. FROM Positions    IMPORT tPosition;
  10. FROM IO        IMPORT StdOutput, WriteS, WriteNl;
  11. FROM Strings    IMPORT tString, IntToString, Concatenate, ArrayToString;
  12. FROM StringMem    IMPORT WriteString;
  13. FROM Idents    IMPORT tIdent, NoIdent, MakeIdent;
  14. FROM Texts    IMPORT WriteText;
  15. FROM Sets    IMPORT IsElement, IsNotEqual, Minimum, Maximum, IsEmpty;
  16. FROM Semantics    IMPORT IdentifyVar, UserTypes, LookupClass;
  17. FROM Optimize    IMPORT NeedsTempo, NeedsMatch, NeedsNoFinale, GetRule;
  18. FROM Tree    IMPORT NoTree, tTree, Options, f, SourceFile, WI, WN;
  19.  
  20. VAR
  21.    RoutineKind    : (kProcedure, kFunction, kPredicate);
  22.    WithCount    ,
  23.    RuleCount    ,
  24.    ListCount    : INTEGER;
  25.    i, j        : CARDINAL;
  26.    rule        ,
  27.    TheClass    ,
  28.    InFormals    ,
  29.    OutFormals    ,
  30.    ReturnFormals,
  31.    Decls    : tTree;
  32.    TheName    : tIdent;
  33.    TemposDone    : BOOLEAN;
  34.  
  35. PROCEDURE WriteLine (Line: tPosition);
  36.    BEGIN
  37.       IF Line.Line # 0 THEN
  38.      IF IsElement (ORD ('6'), Options) THEN
  39.         !# line ! WN (Line.Line); @ "@ WriteS (f, SourceFile); @"@
  40.      ELSE
  41.         !/* line ! WN (Line.Line); @ "@ WriteS (f, SourceFile); @" */@
  42.      END;
  43.       END;
  44.    END WriteLine;
  45.  
  46. PROCEDURE Match (t, Formals: tTree);
  47.    VAR TreeName    : tIdent;
  48.    VAR Pattern    : tTree;
  49.    BEGIN
  50.       IF (t^.Kind = Tree.NoPattern) OR (Formals^.Kind # Tree.Formal) THEN RETURN; END;
  51.       Pattern := t^.OnePattern.Pattern;
  52.       CASE Pattern^.Kind OF
  53.       | Tree.Decompose: WITH Pattern^.Decompose DO
  54.         TreeName := Object^.Class.TypeDesc^.NodeTypes.TreeName^.TreeName.Name;
  55.         IF (Formals^.Formal.TypeDesc^.Kind = Tree.UserType) OR
  56.            IsNotEqual (Object^.Class.TypeDesc^.NodeTypes.Types, Formals^.Formal.TypeDesc^.NodeTypes.Types) THEN
  57.            IF Object^.Class.Extensions^.Kind = Tree.NoClass THEN    (* Low ? *)
  58.           @   if (@ ImplC (Path); @->Kind != k@ WI (Object^.Class.Name);
  59.            ELSE
  60.           @   if (! @ WI (TreeName); @_IsType (@ ImplC (Path); @, k@ WI (Object^.Class.Name); @)@ 
  61.            END;
  62.            !) goto yyL! WN (RuleCount); !;!
  63.         END;
  64.         Match (Patterns, Object^.Class.Formals);
  65.      END;
  66.  
  67.       | Tree.VarDef: WITH Pattern^.VarDef DO
  68.         IF Object # NoTree THEN
  69.            WITH Object^.Formal DO
  70.           @   if (! (equal@ DefC (TypeDesc); @ (@ ImplC (Path);
  71.           !, ! ImplC (Pattern^.VarDef.Path); !))) goto yyL! WN (RuleCount); !;!
  72.            END;
  73.         END;
  74.      END;
  75.  
  76.       | Tree.NilTest:
  77.      !   if (! ImplC (Pattern^.NilTest.Path); @ != NULL) goto yyL@ WN (RuleCount); !;!
  78.  
  79.       | Tree.DontCare1:
  80.       | Tree.DontCare: RETURN;
  81.  
  82.       | Tree.Value: WITH Pattern^.Value DO
  83.         AssignTempo (Expr);
  84.         IF (Formals^.Formal.TypeDesc^.Kind = Tree.UserType) AND
  85.            IsElement (Formals^.Formal.TypeDesc^.UserType.Type, UserTypes) THEN
  86.            !  {! DefC (Formals^.Formal.TypeDesc); ! yyT; yyT = ! Expression (Expr); !;!
  87.            @   if (! (equal@ DefC (Formals^.Formal.TypeDesc);
  88.            ! (! ImplC (Path); !, yyT))) goto yyL! WN (RuleCount); !;!
  89.            !  }!
  90.         ELSE
  91.            @   if (! (equal@ DefC (Formals^.Formal.TypeDesc);
  92.            ! (! ImplC (Path); !, ! Expression (Expr); !))) goto yyL! WN (RuleCount); !;!
  93.         END;
  94.         MatchExpr (Expr);
  95.      END;
  96.       END;
  97.       Match (t^.OnePattern.Next, Formals^.Formal.Next);
  98.    END Match;
  99.  
  100. PROCEDURE MatchExprs (t: tTree);
  101.    BEGIN
  102.       IF t^.Kind = Tree.NoExpr THEN RETURN; END;
  103.       IF t^.OneExpr.Expr^.Kind = Tree.DontCare THEN RETURN; END;
  104.       MatchExpr (t^.OneExpr.Expr);
  105.       MatchExprs (t^.OneExpr.Next);
  106.    END MatchExprs;
  107.  
  108. PROCEDURE MatchExpr (t: tTree);
  109.    BEGIN
  110.       CASE t^.Kind OF
  111.       | Tree.Compose:
  112.      MatchExprs (t^.Compose.Exprs);
  113.  
  114.       | Tree.VarUse    :
  115.       | Tree.Nil    :
  116.       | Tree.DontCare1    :
  117.       | Tree.TargetExpr    :
  118.       | Tree.StringExpr    :
  119.       | Tree.AttrDesc    :
  120.  
  121.       | Tree.Call    : WITH t^.Call DO
  122.         MatchExpr (Expr);
  123.         MatchExprs (Exprs);
  124.         IF Object # NoTree THEN
  125.            Match (Patterns, Object^.Routine.OutForm);
  126.         END;
  127.      END;
  128.  
  129.       | Tree.Binary    : WITH t^.Binary DO
  130.         MatchExpr (Lop);
  131.         MatchExpr (Rop);
  132.      END;
  133.  
  134.       | Tree.PreOperator, Tree.PostOperator    :
  135.      MatchExpr (t^.PreOperator.Expr);
  136.  
  137.       | Tree.Index    :
  138.      MatchExpr (t^.Index.Expr);
  139.      MatchExprs (t^.Index.Exprs);
  140.  
  141.       | Tree.Parents    :
  142.      MatchExpr (t^.Parents.Expr);
  143.       END;
  144.    END MatchExpr;
  145.  
  146. PROCEDURE AssignTempos (t: tTree);
  147.    BEGIN
  148.       IF t^.Kind = Tree.NoExpr THEN RETURN; END;
  149.       IF t^.OneExpr.Expr^.Kind = Tree.DontCare THEN RETURN; END;
  150.       AssignTempo (t^.OneExpr.Expr);
  151.       AssignTempos (t^.OneExpr.Next);
  152.    END AssignTempos;
  153.  
  154. PROCEDURE AssignTempo (t: tTree);
  155.    VAR TreeName    : tIdent;
  156.    BEGIN
  157.       CASE t^.Kind OF
  158.       | Tree.Compose: WITH t^.Compose DO
  159.         TreeName := Object^.Class.TypeDesc^.NodeTypes.TreeName^.TreeName.Name;
  160.         !   yyALLOC (t! WI (TreeName); !,! WI (TreeName); !_PoolFreePtr,! 
  161.         WI (TreeName); !_PoolMaxPtr,! WI (TreeName); !_Alloc,! WI (TreeName);
  162.         !_NodeSize,Make! WI (TreeName); !,! WI (Tempo); !,k! WI (Object^.Class.Name); !)!
  163.         AssignSubFormals (Exprs, Object^.Class.Formals, Tempo, Object^.Class.Name);
  164.      END;
  165.  
  166.       | Tree.VarUse    :
  167.       | Tree.Nil    :
  168.       | Tree.DontCare1    :
  169.       | Tree.TargetExpr    :
  170.       | Tree.StringExpr    :
  171.       | Tree.AttrDesc    :
  172.  
  173.       | Tree.Call    : WITH t^.Call DO
  174.         AssignTempo (Expr);
  175.         AssignTempos (Exprs);
  176.      END;
  177.  
  178.       | Tree.Binary    : WITH t^.Binary DO
  179.         AssignTempo (Lop);
  180.         AssignTempo (Rop);
  181.      END;
  182.  
  183.       | Tree.PreOperator, Tree.PostOperator    :
  184.      AssignTempo (t^.PreOperator.Expr);
  185.  
  186.       | Tree.Index    :
  187.      AssignTempo (t^.Index.Expr);
  188.      AssignTempos (t^.Index.Exprs);
  189.  
  190.       | Tree.Parents    :
  191.      AssignTempo (t^.Parents.Expr);
  192.       END;
  193.    END AssignTempo;
  194.  
  195. PROCEDURE AssignFormals (t, Formals: tTree);
  196.    BEGIN
  197.       IF (t^.Kind = Tree.NoExpr) OR (Formals^.Kind # Tree.Formal) THEN RETURN; END;
  198.       IF t^.OneExpr.Expr^.Kind = Tree.DontCare THEN
  199.      BeginFormals (Formals);
  200.      RETURN;
  201.       END;
  202.       AssignFormal (t^.OneExpr.Expr, Formals);
  203.       MatchExpr (t^.OneExpr.Expr);
  204.       AssignFormals (t^.OneExpr.Next, Formals^.Formal.Next);
  205.    END AssignFormals;
  206.  
  207. PROCEDURE AssignFormal (t, Formals: tTree);
  208.    VAR TreeName, With    : tIdent;
  209.    BEGIN
  210.       IF t^.Kind = Tree.Compose THEN
  211.      WITH t^.Compose DO
  212.         TreeName := Object^.Class.TypeDesc^.NodeTypes.TreeName^.TreeName.Name;
  213.         With := MakeWith ();
  214.         !   {register t! WI (TreeName); ! ! WI (With); !;!
  215.         !    yyALLOC (t! WI (TreeName); !,! WI (TreeName); !_PoolFreePtr,! 
  216.         WI (TreeName); !_PoolMaxPtr,! WI (TreeName); !_Alloc,! WI (TreeName);
  217.         !_NodeSize,Make! WI (TreeName); !,! WI (With); !,k! WI (Object^.Class.Name); !)!
  218.         !    * ! WI (Formals^.Formal.Name); ! = ! WI (With); !;!
  219.         AssignSubFormals (Exprs, Object^.Class.Formals, With, Object^.Class.Name);
  220.         !   }!
  221.      END;
  222.       ELSE
  223.      AssignTempo (t);
  224.       END;
  225.  
  226.       CASE t^.Kind OF
  227.       | Tree.VarUse, Tree.Nil, Tree.Call, Tree.Binary, Tree.PreOperator,
  228.     Tree.PostOperator, Tree.Index, Tree.Parents, Tree.TargetExpr, Tree.StringExpr,
  229.     Tree.AttrDesc:
  230.      !   * ! WI (Formals^.Formal.Name); ! = ! Expression (t); !;!
  231.       | Tree.DontCare1:
  232.      !    begin! DefC (Formals^.Formal.TypeDesc); ! (* ! WI (Formals^.Formal.Name); !)!
  233.       ELSE
  234.       END;
  235.    END AssignFormal;
  236.  
  237. PROCEDURE AssignSubFormals (t, Formals: tTree; PrevWith, Composer: tIdent);
  238.    BEGIN
  239.       IF (t^.Kind = Tree.NoExpr) OR (Formals^.Kind # Tree.Formal) THEN RETURN; END;
  240.       IF t^.OneExpr.Expr^.Kind = Tree.DontCare THEN
  241.      BeginSubFormals (Formals, PrevWith, Composer);
  242.      RETURN;
  243.       END;
  244.       AssignSubFormal (t^.OneExpr.Expr, Formals, PrevWith, Composer);
  245.       AssignSubFormals (t^.OneExpr.Next, Formals^.Formal.Next, PrevWith, Composer);
  246.    END AssignSubFormals;
  247.  
  248. PROCEDURE AssignSubFormal (t, Formals: tTree; PrevWith, Composer: tIdent);
  249.    VAR TreeName, With    : tIdent;
  250.    BEGIN
  251.       IF t^.Kind = Tree.Compose THEN
  252.      WITH t^.Compose DO
  253.         TreeName := Object^.Class.TypeDesc^.NodeTypes.TreeName^.TreeName.Name;
  254.         With := MakeWith ();
  255.         !   {register t! WI (TreeName); ! ! WI (With); !;!
  256.         !    yyALLOC (t! WI (TreeName); !,! WI (TreeName); !_PoolFreePtr,! 
  257.         WI (TreeName); !_PoolMaxPtr,! WI (TreeName); !_Alloc,! WI (TreeName);
  258.         !_NodeSize,Make! WI (TreeName); !,! WI (With); !,k! WI (Object^.Class.Name); !)!
  259.         !    ! WI (PrevWith); !->! WI (Composer); !.! WI (Formals^.Formal.Name); ! = ! WI (With); !;!
  260.         AssignSubFormals (Exprs, Object^.Class.Formals, With, Object^.Class.Name);
  261.         !   }!
  262.      END;
  263.       ELSE
  264.      AssignTempo (t);
  265.       END;
  266.  
  267.       CASE t^.Kind OF
  268.       | Tree.VarUse, Tree.Nil, Tree.Call, Tree.Binary, Tree.PreOperator,
  269.     Tree.PostOperator, Tree.Index, Tree.Parents, Tree.TargetExpr, Tree.StringExpr,
  270.     Tree.AttrDesc:
  271.      !    ! WI (PrevWith); !->! WI (Composer); !.! WI (Formals^.Formal.Name); ! = ! Expression (t); !;!
  272.       | Tree.DontCare1:
  273.      !    begin! DefC (Formals^.Formal.TypeDesc); ! (! WI (PrevWith); !->! WI (Composer); !.! WI (Formals^.Formal.Name); !)!
  274.       ELSE
  275.       END;
  276.    END AssignSubFormal;
  277.  
  278. PROCEDURE BeginFormals (Formals: tTree);
  279.    BEGIN
  280.       IF Formals^.Kind = Tree.Formal THEN
  281.      WITH Formals^.Formal DO
  282.         !    begin! DefC (TypeDesc); ! (* ! WI (Name); !)!
  283.         BeginFormals (Next);
  284.      END;
  285.       END;
  286.    END BeginFormals;
  287.  
  288. PROCEDURE BeginSubFormals (Formals: tTree; PrevWith, Composer: tIdent);
  289.    BEGIN
  290.       IF Formals^.Kind = Tree.Formal THEN
  291.      WITH Formals^.Formal DO
  292.         !    begin! DefC (TypeDesc); ! (! WI (PrevWith); !->! WI (Composer); !.! WI (Name); !)!
  293.         BeginSubFormals (Next, PrevWith, Composer);
  294.      END;
  295.       END;
  296.    END BeginSubFormals;
  297.  
  298. PROCEDURE ConsPatterns (t: tTree; ListCount: INTEGER): INTEGER;
  299.    BEGIN
  300.       IF t^.Kind = Tree.NoPattern THEN RETURN ListCount; END;
  301.       WITH t^.OnePattern DO
  302.      IF Pattern^.Kind = Tree.DontCare THEN
  303.         RETURN ConsTempos (Pattern^.DontCare.Tempos, ListCount, TRUE);
  304.      ELSE
  305.         IF ListCount > 0 THEN !, ! END;
  306.         !& ! WI (Pattern^.Pattern.Tempo);
  307.         RETURN ConsPatterns (Next, ListCount + 1);
  308.      END;
  309.       END;
  310.    END ConsPatterns;
  311.  
  312. PROCEDURE ConsTempos (t: tTree; ListCount: INTEGER; IsRef: BOOLEAN): INTEGER;
  313.    BEGIN
  314.       IF t^.Kind = Tree.Formal THEN
  315.      IF ListCount > 0 THEN !, ! END;
  316.      IF IsRef THEN !& ! END;
  317.      WI (t^.Formal.Name);
  318.      RETURN ConsTempos (t^.Formal.Next, ListCount + 1, IsRef);
  319.       ELSE
  320.      RETURN ListCount;
  321.       END;
  322.    END ConsTempos;
  323.  
  324. PROCEDURE Expressions (t: tTree; ListCount: INTEGER): INTEGER;
  325.    BEGIN
  326.       IF t^.Kind = Tree.NoExpr THEN RETURN ListCount; END;
  327.       WITH t^.OneExpr DO
  328.      IF Expr^.Kind = Tree.DontCare THEN
  329.         RETURN ConsTempos (Expr^.DontCare.Tempos, ListCount, FALSE);
  330.      ELSE
  331.         IF ListCount > 0 THEN !, ! END;
  332.         Expression (Expr);
  333.         RETURN Expressions (Next, ListCount + 1);
  334.      END;
  335.       END;
  336.    END Expressions;
  337.  
  338. PROCEDURE Expressions2 (t: tTree; ListCount: INTEGER; Formals: tTree): INTEGER;
  339.    BEGIN
  340.       IF t^.Kind = Tree.NoExpr THEN RETURN ListCount; END;
  341.       WITH t^.OneExpr DO
  342.      IF Expr^.Kind = Tree.DontCare THEN
  343.         RETURN ConsTempos (Expr^.DontCare.Tempos, ListCount, FALSE);
  344.      ELSE
  345.         IF ListCount > 0 THEN !, ! END;
  346.         IF Formals^.Formal.Path^.Var.IsOutput THEN !& ! END;
  347.         Expression (Expr);
  348.         RETURN Expressions2 (Next, ListCount + 1, Formals^.Formal.Next);
  349.      END;
  350.       END;
  351.    END Expressions2;
  352.  
  353. PROCEDURE Expression (t: tTree);
  354.    BEGIN
  355.       CASE t^.Kind OF
  356.       | Tree.Compose    : WI (t^.Compose.Tempo);
  357.  
  358.       | Tree.Nil    : !NULL! 
  359.  
  360.       | Tree.VarUse    : WITH t^.VarUse DO
  361.         IF Object # NoTree THEN
  362.            ImplC (Object^.Formal.Path);
  363.         ELSE
  364.            WI (Name);
  365.         END;
  366.      END;
  367.  
  368.       | Tree.DontCare1    : WI (t^.DontCare1.Tempo);
  369.  
  370.       | Tree.Call    : WITH t^.Call DO
  371.         Expression (Expr); ! (! 
  372.         IF Object # NoTree THEN
  373.            ListCount := Expressions2 (Exprs, 0, Object^.Routine.InForm);
  374.            ListCount := ConsPatterns (Patterns, ListCount);
  375.         ELSE
  376.            ListCount := Expressions (Exprs, 0);
  377.            ListCount := Expressions (Patterns, ListCount);
  378.         END;
  379.         !)! 
  380.      END;
  381.  
  382.       | Tree.Binary    : WITH t^.Binary DO
  383.         Expression (Lop); ! ! WI (Operator); ! ! Expression (Rop);
  384.      END;
  385.  
  386.       | Tree.PreOperator    :
  387.      WI (t^.PreOperator.Operator); ! ! Expression (t^.PreOperator.Expr);
  388.  
  389.       | Tree.PostOperator    :
  390.      Expression (t^.PostOperator.Expr); ! ! WI (t^.PostOperator.Operator);
  391.  
  392.       | Tree.Index    :
  393.      Expression (t^.Index.Expr); ! [! ListCount := Expressions (t^.Index.Exprs, 0); !]! 
  394.  
  395.       | Tree.Parents    : !(! Expression (t^.Parents.Expr); !)! 
  396.  
  397.       | Tree.TargetExpr    : ImplC (t^.TargetExpr.Expr);
  398.  
  399.       | Tree.StringExpr    : WriteString (f, t^.StringExpr.String);
  400.  
  401.       | Tree.AttrDesc    : WITH t^.AttrDesc DO
  402.         ImplC (Object^.Formal.Path); !->! WI (Type); !.! WI (Attribute);
  403.      END;
  404.       END;
  405.    END Expression;
  406.  
  407. PROCEDURE MakeWith (): tIdent;
  408.    VAR String1, String2    : tString;
  409.    BEGIN
  410.       INC (WithCount);
  411.       ArrayToString ("yyW", String1);
  412.       IntToString (WithCount, String2);
  413.       Concatenate (String1, String2);
  414.       RETURN MakeIdent (String1);
  415.    END MakeWith;
  416. }
  417.  
  418. PROCEDURE MacroC (t: Tree)
  419.  
  420. Spec (..) :- {
  421.     MacroC (TreeNames);
  422. }; .
  423. TreeName (..) :- {
  424.     !# define begint! WI (Name); !(a)    a = NULL;!
  425.     !# define equalt! WI (Name); !(a, b)    IsEqual! WI (Name); ! (a, b)!
  426.     MacroC (Next);
  427. }; .
  428.  
  429.  
  430. PROCEDURE DefC (t: Tree)
  431.  
  432. Spec (..) :- {
  433.     !# ifndef yy! WI (TrafoName); !!
  434.     !# define yy! WI (TrafoName); !!
  435.     !!
  436.     !# if defined __STDC__ | defined __cplusplus!
  437.     !# define ARGS(parameters)    parameters!
  438.     !# else!
  439.     !# define ARGS(parameters)    ()!
  440.     !# endif!
  441.     !!
  442.     !# ifndef bool!
  443.     !# define bool char!
  444.     !# endif!
  445.     !!
  446.     DefC (TreeNames);
  447.     !!
  448.     WriteLine (Codes^.Codes.ImportLine);
  449.     WriteText (f, Codes^.Codes.Import);
  450.     WriteLine (Codes^.Codes.ExportLine);
  451.     WriteText (f, Codes^.Codes.Export);
  452.     !!
  453.     !extern void (* ! WI (TrafoName); !_Exit) ();!
  454.     !!
  455.     DefC (Public);
  456.     !!
  457.     !extern void Begin! WI (TrafoName); ! ();!
  458.     !extern void Close! WI (TrafoName); ! ();!
  459.     !!
  460.     !# endif!
  461. }; .
  462. TreeName (..) :- {
  463.     @# include "@ WI (Name); @.h"@
  464.     DefC (Next);
  465. }; .
  466. Name (..) :- {
  467.     IF Object # NoTree THEN
  468.        ListCount := 0;
  469.        !extern ! 
  470.        IF Object^.Kind = Tree.Procedure THEN
  471.           !void! 
  472.        ELSIF Object^.Kind = Tree.Function THEN
  473.           DefC (Object^.Function.ReturnForm^.Formal.TypeDesc);
  474.        ELSIF Object^.Kind = Tree.Predicate THEN
  475.           !bool! 
  476.        END;
  477.        ! ! WI (Name); ! ARGS((! 
  478.        DefC (Object^.Routine.InForm);
  479.        DefC (Object^.Routine.OutForm);
  480.        !));!
  481.     END;
  482.     DefC (Next);
  483. }; .
  484. Formal (..) :- {
  485.     IF ListCount > 0 THEN !, ! END;
  486.     DefC (TypeDesc);
  487.     IF Path^.Var.IsOutput THEN ! *! END;
  488.     ! ! WI (Name);
  489.     INC (ListCount);
  490.     DefC (Next);
  491. }; .
  492. NodeTypes (..) :- {
  493.     !t! WI (TreeName^.TreeName.Name);
  494. }; .
  495. UserType (..) :- {
  496.     WI (Type);
  497. }; .
  498.  
  499.  
  500. PROCEDURE Forward (t: Tree)
  501.  
  502. Procedure (..) :- {
  503.     ListCount := 0;
  504.     IF NOT IsExtern THEN !static ! END;
  505.     !void ! WI (Name); ! ARGS((! 
  506.     DefC (InForm);
  507.     DefC (OutForm);
  508.     !));!
  509.     Forward (Next);
  510. }; .
  511. Function (..) :- {
  512.     ListCount := 0;
  513.     IF NOT IsExtern THEN !static ! END;
  514.     DefC (ReturnForm^.Formal.TypeDesc); ! ! WI (Name); ! ARGS((! 
  515.     DefC (InForm);
  516.     DefC (OutForm);
  517.     !));!
  518.     Forward (Next);
  519. }; .
  520. Predicate (..) :- {
  521.     ListCount := 0;
  522.     IF NOT IsExtern THEN !static ! END;
  523.     !bool ! WI (Name); ! ARGS((! 
  524.     DefC (InForm);
  525.     DefC (OutForm);
  526.     !));!
  527.     Forward (Next);
  528. }; .
  529.  
  530.  
  531. PROCEDURE ProcHead1 (t: Tree)
  532.  
  533. Formal (..) :- {
  534.     IF ListCount > 0 THEN !, ! END;
  535.     WI (Name);
  536.     INC (ListCount);
  537.     ProcHead1 (Next);
  538. }; .
  539.  
  540.  
  541. PROCEDURE ProcHead2 (t: Tree)
  542.  
  543. Formal (..) :- {
  544.     ! ! 
  545.     IF (TypeDesc^.Kind = Tree.NodeTypes) AND Path^.Var.IsRegister THEN !register ! END;
  546.     ImplC (TypeDesc); IF Path^.Var.IsOutput THEN ! *! END; ! ! WI (Name); !;!
  547.     ProcHead2 (Next);
  548. }; .
  549.  
  550.  
  551. PROCEDURE ProcHead3 (t: Tree)
  552.  
  553. Formal (..) :- {
  554.     IF ListCount > 0 THEN !, ! END;
  555.     IF (TypeDesc^.Kind = Tree.NodeTypes) AND Path^.Var.IsRegister THEN !register ! END;
  556.     ImplC (TypeDesc); IF Path^.Var.IsOutput THEN ! *! END; ! ! WI (Name);
  557.     INC (ListCount);
  558.     ProcHead3 (Next);
  559. }; .
  560.  
  561.  
  562. PROCEDURE ImplC (t: Tree)
  563.  
  564. Spec (..) :- {
  565.     @# include "@ WI (TrafoName); @.h"@
  566.     !# ifdef __cplusplus!
  567.     @extern "C" {@
  568.     @# include "System.h"@
  569.     !}!
  570.     !# else!
  571.     @# include "System.h"@
  572.     !# endif!
  573.     !# include <stdio.h>!
  574.     DefC (TreeNames);
  575.     !!
  576.       IF NOT IsElement (ORD ('m'), Options) THEN
  577.     !# define yyInline!
  578.       END;
  579.     !# ifndef NULL!
  580.     !# define NULL 0L!
  581.     !# endif!
  582.     !# ifndef false!
  583.     !# define false 0!
  584.     !# endif!
  585.     !# ifndef true!
  586.     !# define true 1!
  587.     !# endif!
  588.     !!
  589.     !# ifdef yyInline!
  590.     !# define yyALLOC(tree, free, max, alloc, nodesize, make, ptr, kind) \!
  591.     !  if ((ptr = (tree) free) >= (tree) max) ptr = alloc (); \!
  592.     !  free += nodesize [kind]; \!
  593.     !  ptr->yyHead.yyMark = 0; \!
  594.     !  ptr->Kind = kind;!
  595.     !# else!
  596.     !# define yyALLOC(tree, free, max, alloc, nodesize, make, ptr, kind) ptr = make (kind);!
  597.     !# endif!
  598.     !!
  599.     !# define yyWrite(s) (void) fputs (s, yyf)!
  600.     !# define yyWriteNl (void) fputc ('\n', yyf)!
  601.     !!
  602.     WriteLine (Codes^.Codes.GlobalLine);
  603.     WriteText (f, Codes^.Codes.Global);
  604.     @# include "yy@ WI (TrafoName); @.w"@
  605.     !!
  606.     !static void yyExit () { Exit (1); }!
  607.     !!
  608.     !void (* ! WI (TrafoName); !_Exit) () = yyExit;!
  609.     !!
  610.     !static FILE * yyf = stdout;!
  611.     !!
  612.     !static void yyAbort!
  613.     !# ifdef __cplusplus!
  614.     ! (char * yyFunction)!
  615.     !# else!
  616.     ! (yyFunction) char * yyFunction;!
  617.     !# endif!
  618.     !{!
  619.     @ (void) fprintf (stderr, "Error: module @ WI (TrafoName); @, routine %s failed\n", yyFunction);@
  620.     ! ! WI (TrafoName); !_Exit ();!
  621.     !}!
  622.     !!
  623.     Forward (Routines);
  624.     !!
  625.     ImplC (Routines);
  626.     !void Begin! WI (TrafoName); ! ()!
  627.     !{!
  628.     WriteLine (Codes^.Codes.BeginLine);
  629.     WriteText (f, Codes^.Codes.Begin);
  630.     !}!
  631.     !!
  632.     !void Close! WI (TrafoName); ! ()!
  633.     !{!
  634.     WriteLine (Codes^.Codes.CloseLine);
  635.     WriteText (f, Codes^.Codes.Close);
  636.     !}!
  637. }; .
  638. Procedure (..) :- {
  639.     IF NOT IsExtern THEN !static ! END;
  640.     !void ! WI (Name); !!
  641.     !# if defined __STDC__ | defined __cplusplus!
  642.     ListCount := 0;
  643.     !(! ProcHead3 (InForm); ProcHead3 (OutForm); !)!
  644.     !# else!
  645.     ListCount := 0;
  646.     !(! ProcHead1 (InForm); ProcHead1 (OutForm); !)!
  647.     ProcHead2 (InForm);
  648.     ProcHead2 (OutForm);
  649.     !# endif!
  650.     !{!
  651.     WriteLine (LocalLine);
  652.     WriteText (f, Local);
  653.     RoutineKind := kProcedure;
  654.     InFormals := InForm;
  655.     OutFormals := OutForm;
  656.       IF IsElement (ORD ('n'), Options) THEN
  657.     Tg1 (InForm);
  658.       END;
  659.       IF IsElement (ORD ('b'), Options) THEN
  660.     ImplC (Rules);
  661.         IF IsElement (ORD ('f'), Options) THEN
  662.        @ yyAbort ("@ WI (Name); @");@
  663.         END;
  664.       ELSE
  665.     TemposDone := FALSE;
  666.     CommonTestElim (Decisions);
  667.         IF IsElement (ORD ('f'), Options) AND NOT NeedsNoFinale (Decisions) THEN
  668.        @ yyAbort ("@ WI (Name); @");@
  669.     END;
  670.       END;
  671.     !;!
  672.     !}!
  673.     !!
  674.     ImplC (Next);
  675. }; .
  676. Function (..) :- {
  677.     IF NOT IsExtern THEN !static ! END;
  678.     DefC (ReturnForm^.Formal.TypeDesc); ! ! WI (Name); !!
  679.     !# if defined __STDC__ | defined __cplusplus!
  680.     ListCount := 0;
  681.     !(! ProcHead3 (InForm); ProcHead3 (OutForm); !)!
  682.     !# else!
  683.     ListCount := 0;
  684.     !(! ProcHead1 (InForm); ProcHead1 (OutForm); !)!
  685.     ProcHead2 (InForm);
  686.     ProcHead2 (OutForm);
  687.     !# endif!
  688.     !{!
  689.     WriteLine (LocalLine);
  690.     WriteText (f, Local);
  691.     RoutineKind := kFunction;
  692.     InFormals := InForm;
  693.     OutFormals := OutForm;
  694.     ReturnFormals := ReturnForm;
  695.       IF IsElement (ORD ('b'), Options) THEN
  696.     ImplC (Rules);
  697.     @ yyAbort ("@ WI (Name); @");@
  698.       ELSE
  699.     TemposDone := FALSE;
  700.     CommonTestElim (Decisions);
  701.     IF NOT NeedsNoFinale (Decisions) THEN
  702.        @ yyAbort ("@ WI (Name); @");@
  703.     END;
  704.       END;
  705.     !}!
  706.     !!
  707.     ImplC (Next);
  708. }; .
  709. Predicate (..) :- {
  710.     IF NOT IsExtern THEN !static ! END;
  711.     !bool ! WI (Name); !!
  712.     !# if defined __STDC__ | defined __cplusplus!
  713.     ListCount := 0;
  714.     !(! ProcHead3 (InForm); ProcHead3 (OutForm); !)!
  715.     !# else!
  716.     ListCount := 0;
  717.     !(! ProcHead1 (InForm); ProcHead1 (OutForm); !)!
  718.     ProcHead2 (InForm);
  719.     ProcHead2 (OutForm);
  720.     !# endif!
  721.     !{!
  722.     WriteLine (LocalLine);
  723.     WriteText (f, Local);
  724.     RoutineKind := kPredicate;
  725.     InFormals := InForm;
  726.     OutFormals := OutForm;
  727.       IF IsElement (ORD ('n'), Options) THEN
  728.     Tg1 (InForm);
  729.       END;
  730.       IF IsElement (ORD ('b'), Options) THEN
  731.     ImplC (Rules);
  732.     !  return false;!
  733.       ELSE
  734.     TemposDone := FALSE;
  735.     CommonTestElim (Decisions);
  736.     IF NOT NeedsNoFinale (Decisions) THEN
  737.        !  return false;!
  738.     END;
  739.       END;
  740.     !}!
  741.     !!
  742.     ImplC (Next);
  743. }; .
  744. Rule (..) :- {
  745.     WriteLine (Line);
  746.     IF HasTempos THEN ! {!
  747.     END;
  748.     RuleCount := Index;
  749.     WithCount := 0;
  750.     Decls := VarDecls;
  751.     Declare (Patterns);
  752.     Declare (Exprs);
  753.     Declare (Statements);
  754.     Match (Patterns, InFormals);
  755.     IF Statements^.Kind # Tree.NoStatement THEN
  756.        !  {!
  757.        ImplC (Statements);
  758.        !  }!
  759.     END;
  760.     IF NOT HasRejectOrFail THEN
  761.        AssignFormals (Exprs, OutFormals);
  762.        CASE RoutineKind OF
  763.        | kProcedure: !   return;!
  764.  
  765.        | kFunction :
  766.           IF HasPatterns AND (Expr^.Kind # Tree.Compose) AND (t^.Kind # Tree.DontCare1) THEN
  767.          !  {register ! DefC (ReturnFormals^.Formal.TypeDesc); ! ! WI (Tempo); !;!
  768.          Declare (Expr);
  769.          AssignTempo (Expr);
  770.          !   ! WI (Tempo); ! = ! Expression (Expr); !;!
  771.          MatchExpr (Expr);
  772.          !   return ! WI (Tempo); !;!
  773.          !  }!
  774.           ELSIF HasTempos THEN
  775.          !  {!
  776.          Declare (Expr);
  777.          AssignTempo (Expr);
  778.          MatchExpr (Expr);
  779.          !   return ! Expression (Expr); !;!
  780.          !  }!
  781.           ELSE
  782.          !   return ! Expression (Expr); !;!
  783.           END;
  784.  
  785.        | kPredicate: !   return true;!
  786.        END;
  787.     END;
  788.     IF HasTempos THEN ! }!
  789.     END;
  790.     !yyL! WN (RuleCount); !:;!
  791.     !!
  792.     ImplC (Next);
  793. }; .
  794. ProcCall (..) :- {
  795.     WriteLine (Pos);
  796.     AssignTempo (Call);
  797.     !   ! Expression (Call); !;!
  798.     MatchExpr (Call);
  799.     ImplC (Next);
  800. }; .
  801. Condition (..) :- {
  802.     WriteLine (Pos);
  803.     AssignTempo (Expr);
  804.     @   if (! (@ Expression (Expr); @)) goto yyL@ WN (RuleCount); @;@
  805.     MatchExpr (Expr);
  806.     IF Next^.Kind # Tree.NoStatement THEN
  807.        !  {!
  808.        ImplC (Next);
  809.        !  }!
  810.     END;
  811. }; .
  812. Assignment (..) :- {
  813.     WriteLine (Pos);
  814.     AssignTempo (Adr);
  815.     AssignTempo (Expr);
  816.     IF Object # NoTree THEN
  817.        !   ! ImplC (Object^.Formal.Path);
  818.     ELSE
  819.        !   ! Expression (Adr);
  820.     END;
  821.     ! = ! Expression (Expr); !;!
  822.     MatchExpr (Adr);
  823.     MatchExpr (Expr);
  824.     ImplC (Next);
  825. }; .
  826. Reject (..) :- {
  827.     WriteLine (Pos);
  828.     !   goto yyL! WN (RuleCount); !;!
  829. }; .
  830. Fail (..) :- {
  831.     WriteLine (Pos);
  832.     !   return! IF RoutineKind = kPredicate THEN ! false! END; !;!
  833. }; .
  834. TargetStmt (..) :- {
  835.     WriteLine (Pos);
  836.     ImplC (Stmt); !!
  837.     ImplC (Next);
  838. }; .
  839. Nl (..) :- {
  840.     WriteLine (Pos);
  841.     !   yyWriteNl;!
  842.     ImplC (Next);
  843. }; .
  844. WriteStr (..) :- {
  845.     WriteLine (Pos);
  846.     !   yyWrite (! WriteString (f, String); !);!
  847.     ImplC (Next);
  848. }; .
  849. Ident (..) :- Var: tTree; {
  850.     Var := IdentifyVar (Decls, Attribute);
  851.     IF Var # NoTree THEN ImplC (Var^.Formal.Path); ELSE WI (Attribute); END;
  852.     ImplC (Next);
  853. }; .
  854. Any (..) :- {
  855.     WriteString (f, Code);
  856.     ImplC (Next);
  857. }; .
  858. Anys (..) :- {
  859.     ImplC (Layouts);
  860.     ImplC (Next);
  861. }; .
  862. LayoutAny (..) :- {
  863.     WriteString (f, Code);
  864.     ImplC (Next);
  865. }; .
  866. Designator (..) :- {
  867.     ImplC (Object^.Formal.Path); !->! WI (Type); !.! WI (Attribute);
  868.     ImplC (Next);
  869. }; .
  870. Field (..) :- {
  871.     ImplC (Next);
  872.     !.! WI (Name);
  873. }; .
  874. ConsType (..) :- {
  875.     ImplC (Next);
  876.     !->! WI (Name);
  877. }; .
  878. Var (..) :- {
  879.     IF IsOutput THEN
  880.        !(* ! WI (Name); !)! 
  881.     ELSE
  882.        WI (Name);
  883.     END;
  884. }; .
  885. NodeTypes (..) :- {
  886.     !t! WI (TreeName^.TreeName.Name);
  887. }; .
  888. UserType (..) :- {
  889.     IF NOT IsElement (Type, UserTypes) THEN !register ! END; WI (Type);
  890. }; .
  891.  
  892.  
  893. PROCEDURE Declare (t: Tree)    /* reads GLOBAL Decls */
  894.  
  895. Formal (..) :- {
  896.     !  ! DefC (TypeDesc); ! ! WI (Name); !;!
  897.     Declare (Next);
  898. }; .
  899. Param (..) :- Var: tTree; {
  900.     Var := IdentifyVar (Decls, Name);
  901.     !  ! DefC (Var^.Formal.TypeDesc); ! ! WI (Name); !;!
  902.     Declare (Next);
  903. }; .
  904. ProcCall (..) :- {
  905.     Declare (Call);
  906.     Declare (Next);
  907. }; .
  908. Condition (..) :- {
  909.     Declare (Expr);
  910.     Declare (Next);
  911. }; .
  912. Assignment (..) :- {
  913.     Declare (Adr);
  914.     Declare (Expr);
  915.     Declare (Next);
  916. }; .
  917. TargetStmt (..) :- {
  918.     Declare (Parameters);
  919.     Declare (Next);
  920. }; .
  921. Statement (..) :- {
  922.     Declare (Next);
  923. }; .
  924. OnePattern (..) :- {
  925.     IF (Pattern^.Pattern.Tempo # NoIdent) AND (Pattern^.Kind # Tree.DontCare1) THEN
  926.        !  ! DefC (Pattern^.Pattern.TypeDesc); ! ! WI (Pattern^.Pattern.Tempo); !;!
  927.     END;
  928.     Declare (Pattern);
  929.     Declare (Next);
  930. }; .
  931. OneExpr (..) :- {
  932.     Declare (Expr);
  933.     Declare (Next);
  934. }; .
  935. Decompose (..) :- {
  936.     Declare (Patterns);
  937. }; .
  938. DontCare (..) :- {
  939.     Declare (Tempos);
  940. }; .
  941. DontCare1 (..) :- {
  942.     IF Tempo # NoIdent THEN
  943.        !  ! DefC (TypeDesc); ! ! WI (Tempo); !;!
  944.     END;
  945. }; .
  946. Value (..) :- {
  947.     Declare (Expr);
  948. }; .
  949. Compose (..) :- {
  950.     IF Tempo # NoIdent THEN
  951.        !  register ! DefC (TypeDesc); ! ! WI (Tempo); !;!
  952.     END;
  953.     Declare (Exprs);
  954. }; .
  955. Call (..) :- {
  956.     Declare (Expr);
  957.     Declare (Exprs);
  958.     Declare (Patterns);
  959. }; .
  960. Binary (..) :- {
  961.     Declare (Lop);
  962.     Declare (Rop);
  963. }; .
  964. PreOperator (..) ;
  965. PostOperator (..) ;
  966. Parents (..) :- {
  967.     Declare (Expr); 
  968. }; .
  969. Index (..) :- {
  970.     Declare (Expr);
  971.     Declare (Exprs);
  972. }; .
  973.  
  974.  
  975. PROCEDURE Tg1 (t: Tree)
  976.  
  977. Formal (..) :- {
  978.     TheName := Name;
  979.     Tg1 (TypeDesc);
  980.     Tg1 (Next);
  981. }; .
  982. NodeTypes (..) :- {
  983.     !  if (! WI (TheName); ! == No! WI (TreeName^.TreeName.Name);
  984.     !) return! IF RoutineKind = kPredicate THEN ! false! END; !;!
  985. }; .
  986.  
  987.  
  988. PROCEDURE CommonTestElim (t: Tree)
  989.  
  990. Decision (..) :- {
  991.     IF Cases = 0 THEN
  992.        IF NOT TemposDone AND (OneTest^.Kind = Tree.TestValue) AND NeedsTempo (Then, rule) THEN
  993.           ! {!
  994.           TemposDone := TRUE;
  995.           WITH rule^.Rule DO
  996.          RuleCount := Index;
  997.          Decls := VarDecls;
  998.          Declare (Patterns);
  999.          Declare (Exprs);
  1000.          Declare (Statements);
  1001.           END;
  1002.           CommonTestElim (OneTest);
  1003.           CommonTestElim (Then);
  1004.           !  }!
  1005.           ! }!
  1006.        ELSE
  1007.           GetRule (Then, rule);
  1008.           Decls := rule^.Rule.VarDecls;
  1009.           CommonTestElim (OneTest);
  1010.           CommonTestElim (Then);
  1011.           !  }!
  1012.        END;
  1013.        IF (OneTest^.Kind = Tree.TestValue) AND
  1014.           (OneTest^.TestValue.TypeDesc^.Kind = Tree.UserType) AND
  1015.            IsElement (OneTest^.TestValue.TypeDesc^.UserType.Type, UserTypes) THEN
  1016.           !  }!
  1017.        END;
  1018.        TemposDone := FALSE;
  1019.        CommonTestElim (Else);
  1020.     ELSE
  1021.        i := Cases; Case (t);
  1022.     END;
  1023. }; .
  1024. Decided (..) :- {
  1025.     CommonTestElim (Rule);
  1026.     IF Rule^.Rule.HasExit THEN
  1027.        TemposDone := FALSE;
  1028.        CommonTestElim (Else);
  1029.     END;
  1030. }; .
  1031. TestKind (..) :- {
  1032.     !  if (! ImplC (Path); !->Kind == k! WI (Name); !) {!
  1033. }; .
  1034. TestIsType (..) :- {
  1035.     !  if (! WI (TypeDesc^.NodeTypes.TreeName^.TreeName.Name); !_IsType (! ImplC (Path);
  1036.        !, k! WI (Name); !)) {!
  1037. }; .
  1038. TestNil (..) :- {
  1039.     !  if (! ImplC (Path); ! == NULL) {!
  1040. }; .
  1041. TestNonlin (..) :- {
  1042.     !  if (equal! DefC (TypeDesc); ! (! ImplC (Path); !, ! ImplC (Path2); !)) {!
  1043. }; .
  1044. TestValue (_, _, _, UserType (Type)) :-
  1045.     (IsElement (Type, UserTypes));
  1046. {
  1047.     AssignTempo (Expr);
  1048.     !  {! DefC (TypeDesc); ! yyT; yyT = ! Expression (Expr); !;!
  1049.     MatchExpr (Expr);
  1050.     !  if (equal! DefC (TypeDesc); ! (! ImplC (Path); !, yyT)) {!
  1051. }; .
  1052. TestValue (..) :- {
  1053.     AssignTempo (Expr);
  1054.     !  if (equal! DefC (TypeDesc); ! (! ImplC (Path); !, ! Expression (Expr); !)) {!
  1055.     MatchExpr (Expr);
  1056. }; .
  1057. Rule (..) :- {
  1058.     WriteLine (Line);
  1059.     RuleCount := Index;
  1060.     WithCount := 0;
  1061.     Decls := VarDecls;
  1062.     IF HasTempos AND NOT TemposDone THEN ! {!
  1063.        Declare (Patterns);
  1064.        Declare (Exprs);
  1065.        Declare (Statements);
  1066.     END;
  1067.     IF Statements^.Kind # Tree.NoStatement THEN
  1068.        !  {!
  1069.        ImplC (Statements);
  1070.        !  }!
  1071.     END;
  1072.     IF NOT HasRejectOrFail THEN
  1073.        AssignFormals (Exprs, OutFormals);
  1074.        CASE RoutineKind OF
  1075.        | kProcedure: !   return;!
  1076.  
  1077.        | kFunction :
  1078.           IF HasPatterns AND (Expr^.Kind # Tree.Compose) AND (t^.Kind # Tree.DontCare1) THEN
  1079.          !  {register ! DefC (ReturnFormals^.Formal.TypeDesc); ! ! WI (Tempo); !;!
  1080.          Declare (Expr);
  1081.          AssignTempo (Expr);
  1082.          !   ! WI (Tempo); ! = ! Expression (Expr); !;!
  1083.          MatchExpr (Expr);
  1084.          !   return ! WI (Tempo); !;!
  1085.          !  }!
  1086.           ELSIF HasTempos THEN
  1087.          !  {!
  1088.          Declare (Expr);
  1089.          AssignTempo (Expr);
  1090.          MatchExpr (Expr);
  1091.          !   return ! Expression (Expr); !;!
  1092.          !  }!
  1093.           ELSE
  1094.          !   return ! Expression (Expr); !;!
  1095.           END;
  1096.  
  1097.        | kPredicate: !   return true;!
  1098.        END;
  1099.     END;
  1100.     IF HasTempos AND NOT TemposDone THEN ! }!
  1101.     END;
  1102.     IF HasExit OR NeedsMatch (Tests) THEN !yyL! WN (RuleCount); !:;!
  1103.     END;
  1104.     !!
  1105. }; .
  1106.  
  1107.  
  1108. PROCEDURE Case (t: Tree)    /* reads GLOBAL i */
  1109.  
  1110. Decision (..) :- n: CARDINAL; {
  1111.     !!
  1112.     !  switch (! ImplC (OneTest^.OneTest.Path); !->Kind) {!
  1113.     n := i;
  1114.     WHILE n > 0 DO
  1115.        IF NOT IsEmpty (t^.Decision.OneTest^.TestIsType.TypeDesc^.NodeTypes.Types) THEN
  1116.           Case (t^.Decision.OneTest);
  1117.           CommonTestElim (t^.Decision.Then);
  1118.           IF NOT NeedsNoFinale (t^.Decision.Then) THEN
  1119.          !  break;!
  1120.           END;
  1121.        END;
  1122.        t := t^.Decision.Else;
  1123.        DEC (n);
  1124.     END;
  1125.     !  }!
  1126.     !!
  1127.     CommonTestElim (t);
  1128. }; .
  1129. TestKind (..) :- {
  1130.     !  case k! WI (Name); !:!
  1131. }; .
  1132. TestIsType (..) :- {
  1133.     Case (TypeDesc);
  1134. }; .
  1135. NodeTypes (..) :- {
  1136.     FOR j := Minimum (Types) TO Maximum (Types) DO
  1137.        IF IsElement (j, Types) THEN
  1138.           TheClass := LookupClass (TreeName^.TreeName.Classes, j);
  1139.           !  case k! WI (TheClass^.Class.Name); !:!
  1140.        END;
  1141.     END;
  1142. }; .
  1143.